package com.lin.filegraph.utils.name;


import com.lin.filegraph.utils.threshold.Threshold;
import com.lin.filegraph.utils.analyze.Language;
import com.lin.filegraph.utils.compdg.ComponentNode;

/**
 * 计算两个目录的目录层次相似度
 *
 * @author WDD
 */
public class DirSimilarity {

    /**
     * 去除编号，根据目录获取相似度
     */
    public static double getSimLevelOfNode(ComponentNode cn1, ComponentNode cn2) {
        if(cn1.getID()>=0&&cn2.getID()>=0){
            String dirPath1 = removeNum(cn1.getStrComponentName(),cn1.getID() );
            String dirPath2 = removeNum(cn2.getStrComponentName(), cn2.getID());
            return getSimLevelOfPath(dirPath1, dirPath2);
        }else{
            return getSimLevelOfPath(cn1.getStrComponentName(), cn2.getStrComponentName());
        }
    }

    /**
     * 根据目录获取相似度
     */
    public static double getSimLevelOfPath(String dirPath1, String dirPath2) {
        dirPath1 = getRelPath(dirPath1);
        dirPath2 = getRelPath(dirPath2);
        String[] arrDirPath1 = dirPath1.split("/");
        String[] arrDirPath2 = dirPath2.split("/");
        int minLength = Math.min(arrDirPath1.length, arrDirPath2.length);
        int countOfOverlap = 0;
        for (int i = 0; i < minLength; i++) {
            if (arrDirPath1[i].equals(arrDirPath2[i])) {
                countOfOverlap++;
            } else {
                break;
            }
        }
        // double similarity = (double) (countOfOverlap+1) / (double)
        // (arrDirPath1.length + arrDirPath2.length - countOfOverlap);
        double similarity = (double) (countOfOverlap) / (Math.max(arrDirPath1.length, arrDirPath2.length));
        // return Threshold.getDirGrade(similarity);
        return similarity;
    }

    /**
     * 去除编号，获取共同路径
     */
    public static String getSimByNode(ComponentNode cn1, ComponentNode cn2) {
        String dirPath1 = removeNum(cn1.getStrComponentName(),cn1.getID() );
        String dirPath2 = removeNum(cn2.getStrComponentName(), cn2.getID());
        return getSimByPath(dirPath1, dirPath2);
    }

    /**
     * 获取共同路径
     */
    public static String getSimByPath(String dirPath1, String dirPath2) {
        dirPath1 = getRelPath(dirPath1);
        dirPath2 = getRelPath(dirPath2);
        String[] arrDirPath1 = dirPath1.split("/");
        String[] arrDirPath2 = dirPath2.split("/");
        int minLength = Math.min(arrDirPath1.length, arrDirPath2.length);
        StringBuffer simPath = new StringBuffer();
        for (int i = 0; i < minLength; i++) {
            if (arrDirPath1[i].equals(arrDirPath2[i])) {
                if (!simPath.toString().equals(""))
                    simPath.append("/");
                simPath.append(arrDirPath1[i]);
            } else {
                break;
            }
        }
        return simPath.toString();
    }

    /**
     * 获得简单名
     */
    public static String getSimpleName(String name) {
        if (name.contains(".")&&isFile(name)) {
            name =name.substring(name.lastIndexOf("/")+1,name.lastIndexOf("."));
            return name;
        }
        String[] parts=null;
        if(name.contains("/")){
            parts=name.split("/");
        }
        String simple =null;
        if(parts==null||parts.length<2)
            simple=name;
        else {
            simple=parts[parts.length-2]+"/"+parts[parts.length-1];
        }
        return simple;
    }

    public static String getRelPath(String filePath) {
        if (filePath.contains(".")&&isFile(filePath)) {
            if (filePath.contains("/"))
                filePath = filePath.substring(0, filePath.lastIndexOf("/"));
            else
                filePath = Threshold.ROOT;
        }
        return filePath;
    }

    /**
     * 判断是否为c、c++、java文件
     */
    public static boolean isFile(String file) {
        for (Language.C c : Language.C.values())
            if (file.endsWith("." + c.toString()))
                return true;
        for (Language.CPlus c : Language.CPlus.values())
            if (file.endsWith("." + c.toString()))
                return true;
        for (Language.Java j : Language.Java.values())
            if (file.endsWith("." + j.toString()))
                return true;
        return false;
    }

    private static String removeNum(String file, int num) {
        if (file.endsWith(Threshold.SPACER + num))
            file = file.replaceAll(Threshold.SPACER + num, "");
        return file;
    }


}

